

import base64
import urllib

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import json
import time
import hashlib
import uuid
import requests
import codecs


proxies={
    'http': '127.0.0.1:7890',
    'https': '127.0.0.1:7890',
}
##### -------- 参数工具函数 -------- #####

def generate_mcode(appid, dev, udid, version):
    concatenated = appid + dev + udid + version
    with_salt = concatenated.lower() + "IO2#!spopqd"
    hash1 = hashlib.md5(with_salt.encode('utf-8')).hexdigest()
    hash2 = hashlib.md5(hash1.encode('utf-8')).hexdigest()
    hash3 = hashlib.md5(hash2.encode('utf-8')).hexdigest()
    return hash3.upper()[:8]

def md5(text):
    return hashlib.md5(text.encode("utf-8")).hexdigest()

def md5_hash(s, substring=True):
    if not s:
        return None
    try:
        md5er = hashlib.md5()
        md5er.update(s.encode('utf-8'))
        hash_hex = md5er.hexdigest()
        return hash_hex[8:24] if substring else hash_hex
    except Exception as e:
        print(f"MD5哈希失败: {e}")
        return None

def generate_udid():
    random_uuid = str(uuid.uuid4())
    udid = md5_hash(random_uuid)
    return udid

def get_flag(key, appid, udid, version, timestamp):
    tmp = key + appid + udid + version + timestamp
    jiami1 = md5(tmp)
    jiami2 = md5(jiami1)
    return jiami2

def generate_webcode(_udid, _appid, _v, _version):
    initial_str = f"{_udid},,{_appid},{_v},{_version}".lower()
    result = initial_str
    for _ in range(3):
        result = hashlib.md5(result.encode()).hexdigest().lower()
    return result[:20]

##### -------- AES加密工具 -------- #####

class ZakerEncryption:
    def encrypt(self, key_str, data_str):
        try:
            if not key_str or not data_str:
                return ""
            key = self._create_key(key_str)
            cipher = AES.new(key, AES.MODE_ECB)
            data_bytes = data_str.encode('utf-8')
            padded_data = pad(data_bytes, AES.block_size)
            encrypted_bytes = cipher.encrypt(padded_data)
            encrypted_base64 = base64.b64encode(encrypted_bytes).decode('utf-8')
            return encrypted_base64
        except Exception as e:
            print(f"加密错误: {e}")
            return ""

    def _create_key(self, key_str):
        key_bytes = key_str.encode('utf-8')
        if len(key_bytes) < 16:
            key_bytes = key_bytes.ljust(16, b'\0')
        elif len(key_bytes) > 16:
            key_bytes = key_bytes[:16]
        return key_bytes

##### -------- 数据结构和参数生成 -------- #####

def get_zaker_data_payload():
    key = "amJKJsirodlsd129"
    appid = "AndroidPhone"
    dev = "39"
    v = "9.1.5"
    version = "9.08"
    brand = "Redmi"
    os_str = "13_23013RK75C"
    os_name = "23013RK75C"
    req_time = int(time.time())
    udid = generate_udid()

    list_data = [
        {
            "local_ip": "",
            "url": "https://iphone.myzaker.com/zaker/interaction.php?_appid=AndroidPhone&_brand=Redmi&_clicode=xxx&_dev=39&_mcode=xxx&_only_read=N&_os=13_23013RK75C&_os_name=23013RK75C&_udid={udid}&_v=9.1.5&_version=9.08&appType=normal".format(udid=udid),
            "net_type": "wifi",
            "req_type": "local",
            "e_type": "2",
            "return_time": "3.23",
            "dtime": str(req_time)
        },
        {
            "local_ip": "",
            "url": "https://iphone.myzaker.com/zaker/app_style.php?_appid=AndroidPhone&_brand=Redmi&_clicode=xxx&_dev=39&_flag=xxx&_mcode=xxx&_only_read=N&_os=13_23013RK75C&_os_name=23013RK75C&_time={time}&_udid={udid}&_v=9.1.5&_version=9.08&appType=normal&sign_arg=app_style|_appid,_nudid,_udid,_uid,_version".format(time=req_time,udid=udid),
            "net_type": "wifi",
            "req_type": "local",
            "e_type": "2",
            "return_time": "3.26",
            "dtime": str(req_time)
        },
        {
            "local_ip": "",
            "url": "https://iphone.myzaker.com/zaker/ar_data/ar_list.php?_appid=AndroidPhone&_brand=Redmi&_clicode=xxx&_dev=39&_mcode=xxx&_only_read=N&_os=13_23013RK75C&_os_name=23013RK75C&_udid={udid}&_v=9.1.5&_version=9.08&appType=normal".format(udid=udid),
            "net_type": "wifi",
            "req_type": "local",
            "e_type": "2",
            "return_time": "3.363",
            "dtime": str(req_time)
        }
    ]

    data = {
        "bd_return_size": "71.5791",
        "bd_net_type": "wifi",
        "bd_return_time": "0.358",
        "bd_dtime": str(req_time),
        "list": list_data
    }

    mcode = generate_mcode(appid, dev, udid, v)
    encryptor = ZakerEncryption()
    data_json = json.dumps(data, separators=(',', ':'))
    encrypted_result = encryptor.encrypt(key, data_json)

    return {
        "data_str": data_json,
        "encrypted": encrypted_result,
        "udid": udid,
        "mcode": mcode,
        "timestamp": str(req_time)
    }

##### -------- 接口一：数据加密POST上报 -------- #####
def generate_clicode(android_id="b9d0a4eaadbef9d1", msa_oa_id="d4dcd1df6253de3b", net="wifi", screen_size="1080_1920"):
    """
    生成ZAKER应用的_clicode参数

    返回:
    生成的_clicode参数（URL编码后）
    """
    # 构建设备信息JSON
    device_info = {
        "_android_id": android_id,
        "_msa_oa_id": msa_oa_id,
        "_net": net,
        "_bsize": screen_size,
        "_imei": msa_oa_id
    }

    # 将JSON转为字符串
    json_str = json.dumps(device_info, separators=(',', ':'))

    # AES加密
    cipher = AES.new("amJKJsirodlsd129".encode('utf-8'), AES.MODE_ECB)
    padded_data = pad(json_str.encode('utf-8'), AES.block_size)
    encrypted_data = cipher.encrypt(padded_data)

    # Base64编码
    base64_str = base64.b64encode(encrypted_data).decode('utf-8')

    # URL编码
    return urllib.parse.quote(base64_str)


def request_zaker_first(data_code, udid, mcode):
    url = "https://iphone.myzaker.com/urlcheck/app_net.php"
    headers = {
        "Host": "iphone.myzaker.com",
        "User-Agent": "okhttp/4.2.2",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    params = {
        "_no_track": "Y"
    }
    data = {
        "data_code": data_code,
        "_os": "13_23013RK75C",
        "_icode": "d4dcd1df6253de3b",
        "_msa_oa_id": "d4dcd1df6253de3b",
        "_os_name": "23013RK75C",
        "_mcode": mcode,
        "_net": "wifi",
        "_bsize": "1080_1920",
        "_only_read": "N",
        "appType": "normal",
        "_v": "9.1.5",
        "_udid": udid,
        "_dev": "39",
        "_appid": "AndroidPhone",
        "_android_id": "b9d0a4eaadbef9d1",
        "_version": "9.08",
        "_brand": "Redmi"
    }

    response = requests.post(url, headers=headers, params=params, data=data)
    print("接口一 状态码:", response.status_code)
    print("接口一 返回内容:", response.text)
    return response.text

##### -------- 接口二：带签GET搜索 -------- #####

def request_zaker_search(keyword="特朗普", udid=None):
    url = "https://search.myzaker.com/api/"
    appid = "AndroidPhone"
    _v = "9.1.5"
    _version = "9.08"
    _dev = "39"
    _time = str(int(time.time()))
    key = "WvT6dYtChFRdb7yKsearch"

    if not udid:
        udid = generate_udid()
    mcode = generate_mcode(appid, _dev, udid, _v)
    flag = get_flag(key, appid, udid, _version, _time)
    webcode = generate_webcode(udid.lower(), appid.lower(), _v.lower(), _version.lower())

    headers = {
        "Host": "search.myzaker.com",
        "User-Agent": "Mozilla/5.0 (Linux; Android 13; 23013RK75C Build/TKQ1.220905.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/138.0.7204.179 Mobile Safari/537.36 ZAKER/9.1.5",
        "Accept": "text/html,application/xhtml+xml,application/xml",
        "X-Requested-With": "com.myzaker.ZAKER_Phone",
        "appinfo": "zaker 9.1.5 androidphone",
    }

    params = {
        "_webcode": webcode,
        "_flag": flag,
        "_os": "13_23013RK75C",
        "sign_arg": "search|_appid,_udid,_uid,_version,keyword",
        "app_ids": "660,310000,13,9,4,11542,5,7,3,8,10530,14,11581,14733",
        "_os_name": "23013RK75C",
        "_mcode": mcode,
        "_only_read": "N",
        "_clicode": generate_clicode(),
        "appType": "normal",
        "_v": _v,
        "_udid": udid,
        "_appid": appid,
        "_dev": _dev,
        "keyword": keyword,
        "full_arg": "_udid",
        "_version": _version,
        "_time": _time,
        "_brand": "Redmi"
    }
    response = requests.get(url, headers=headers, params=params,proxies=proxies)
    print("接口二 状态码:", response.status_code)
    try:
        decoded = codecs.decode(response.text, 'unicode_escape')
    except Exception:
        decoded = response.text
    print("接口二 内容:", decoded[:2000])  # 防止太长，这里仅显示前2000字
    return decoded

##### -------- RUN MAIN -------- #####

if __name__ == '__main__':
    # 1. 数据加密&参数自动生成
    payload = get_zaker_data_payload()
    encrypted = payload["encrypted"]
    udid = payload["udid"]
    mcode = payload["mcode"]
    print("encrypted:", encrypted)
    print("udid:", udid)
    print("mcode:", mcode)
    print("\n============== 请求接口一：POST加密数据 ==============\n")
    request_zaker_first(encrypted, udid, mcode)

    print("\n============== 请求接口二：GET搜索接口 ==============\n")
    request_zaker_search("特朗普", udid)

